package com.eduagent.xwqeduagent.controller;

import com.eduagent.xwqeduagent.common.BaseResponse;
import com.eduagent.xwqeduagent.common.ResultUtils;
import com.eduagent.xwqeduagent.model.dto.MedicalRecordRequest;
import com.eduagent.xwqeduagent.service.MedicalRecordExtractor;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.nio.charset.StandardCharsets;

/**
 * 医院病历处理控制器
 */
@RestController
@RequestMapping("/api/medical")
@Slf4j
@Tag(name = "医疗病历处理", description = "提供医院病历HTML转JSON的功能")
public class MedicalRecordController {

    @Resource
    private MedicalRecordExtractor medicalRecordExtractor;

    @PostMapping("/extract")
    @Operation(summary = "病历结构化提取(文本)", description = "将医院病历HTML内容转换为结构化JSON格式")
    public BaseResponse<String> extractMedicalRecord(@RequestBody MedicalRecordRequest request) {
        log.info("接收病历转换请求，HTML长度: {}", request.getHtmlContent().length());
        String jsonResult = medicalRecordExtractor.extractMedicalRecordToJson(request.getHtmlContent());
        return ResultUtils.success(jsonResult);
    }
    
    @PostMapping("/extract/file")
    @Operation(summary = "病历结构化提取(文件)", description = "上传医院病历HTML文件并转换为结构化JSON格式")
    public BaseResponse<String> extractMedicalRecordFromFile(@RequestParam("file") MultipartFile file) {
        try {
            if (file.isEmpty()) {
                return new BaseResponse<>(40001, null, "上传文件为空");
            }
            
            // 获取文件名和文件大小，记录日志
            String fileName = file.getOriginalFilename();
            log.info("接收病历文件转换请求，文件名: {}, 大小: {}KB", 
                    fileName, file.getSize() / 1024.0);
            
            // 检测文件编码
            byte[] fileBytes = file.getBytes();
            String detectedCharset = detectCharset(fileBytes);
            log.info("检测到的文件编码: {}", detectedCharset);
            
            // 读取文件内容，确保使用正确的编码
            String htmlContent;
            if (detectedCharset != null) {
                htmlContent = new String(fileBytes, detectedCharset);
            } else {
                // 如果无法检测到编码，尝试使用UTF-8
                htmlContent = new String(fileBytes, StandardCharsets.UTF_8);
            }
            
            // 调用服务进行转换
            String jsonResult = medicalRecordExtractor.extractMedicalRecordToJson(htmlContent);
            
            return ResultUtils.success(jsonResult);
        } catch (IOException e) {
            log.error("文件读取失败", e);
            return new BaseResponse<>(50001, null, "文件读取失败: " + e.getMessage());
        } catch (Exception e) {
            log.error("病历转换失败", e);
            return new BaseResponse<>(50002, null, "病历转换失败: " + e.getMessage());
        }
    }
    
    /**
     * 简单的编码检测方法
     * 通过BOM标记和常见特征判断文件编码
     * @param bytes 文件字节数组
     * @return 检测到的编码，如果无法确定则返回null
     */
    private String detectCharset(byte[] bytes) {
        if (bytes.length >= 3) {
            // 检测BOM标记
            if (bytes[0] == (byte)0xEF && bytes[1] == (byte)0xBB && bytes[2] == (byte)0xBF) {
                return StandardCharsets.UTF_8.name();
            }
            if (bytes.length >= 4 && bytes[0] == (byte)0xFF && bytes[1] == (byte)0xFE && 
                    bytes[2] == (byte)0x00 && bytes[3] == (byte)0x00) {
                return "UTF-32LE";
            }
            if (bytes.length >= 4 && bytes[0] == (byte)0x00 && bytes[1] == (byte)0x00 && 
                    bytes[2] == (byte)0xFE && bytes[3] == (byte)0xFF) {
                return "UTF-32BE";
            }
            if (bytes.length >= 2 && bytes[0] == (byte)0xFF && bytes[1] == (byte)0xFE) {
                return StandardCharsets.UTF_16LE.name();
            }
            if (bytes.length >= 2 && bytes[0] == (byte)0xFE && bytes[1] == (byte)0xFF) {
                return StandardCharsets.UTF_16BE.name();
            }
        }
        
        // 如果没有BOM，尝试根据内容特征判断
        boolean hasHighBit = false;
        boolean isGBK = false;
        
        for (int i = 0; i < bytes.length - 1; i++) {
            // 检查高位字节
            if ((bytes[i] & 0x80) != 0) {
                hasHighBit = true;
                
                // GBK双字节特征
                if (i + 1 < bytes.length && 
                    (bytes[i] & 0xFF) >= 0x81 && (bytes[i] & 0xFF) <= 0xFE && 
                    (bytes[i+1] & 0xFF) >= 0x40 && (bytes[i+1] & 0xFF) <= 0xFE) {
                    isGBK = true;
                }
            }
        }
        
        if (isGBK) {
            return "GBK";
        }
        
        if (hasHighBit) {
            // 如有高位字节但无法确定，默认使用UTF-8
            return StandardCharsets.UTF_8.name();
        }
        
        // ASCII文本，使用UTF-8也兼容
        return StandardCharsets.UTF_8.name();
    }
} 